// 设计相关服务(表五工程建设其它费计算)
package services

import (
	"bsm/config"
	"bsm/logger"
	"fmt"
	"math"
	"strconv"
)

// 工程建设其他费项
type OtherCostItem struct {
	// ID           string
	LineNumber   int     `json:"line_number"`   // 表格行号(1,2,3...)
	SerialNumber string  `json:"serial_number"` // 表格序号(1,2,3...)
	Name         string  `json:"name"`          // 费用名称
	Basis        string  `json:"basis"`         // 计算基础
	ExcludingTax float64 `json:"excluding_tax"` // 除税价金额(手工输入)
	VAT          float64 `json:"vat"`           // 增值税金额(可自动计算)
	IncludingTax float64 `json:"including_tax"` // 含税价金额(可自动计算或手工输入)
	Remark       string  `json:"note"`          // 备注
	IsSubItem    bool    `json:"is_sub_item"`   // 是否为子项(如"其中：勘察费")
	ParentID     string  `json:"parent_id"`     // 父项ID(如果是子项)
}

// 工程建设其他费预算表
type OtherConstructionCost struct {
	DesignCode string // 设计编号
	DesignType int
	VatRate    float64                   // 增值税率
	SafeRate   float64                   // 安全生产费率
	Items      map[string]*OtherCostItem // 费用项列表
	Totals     map[string]float64        // 汇总数据: "excluding_tax", "vat", "including_tax"
}

// 计算增值税和含税价(如需要)
func (item *OtherCostItem) CalculateTax(vatRate float64) {
	if item.IncludingTax > 0 && item.ExcludingTax == 0 {
		// 如果含税价有值但除税价为0，则反算
		item.ExcludingTax = item.IncludingTax / (1 + vatRate)
		item.VAT = item.IncludingTax - item.ExcludingTax
	} else if item.ExcludingTax > 0 {
		// 如果除税价有值，则正算
		item.VAT = item.ExcludingTax * vatRate
		item.IncludingTax = item.ExcludingTax + item.VAT
	}
}

// 计算总计(参数: Cost 表二除税总金额, vatRate 增值税率,safeRate 安全生产费率)
func (occ *OtherConstructionCost) CalculateTab5(Cost float64) {
	var totalExcludingTax, totalVAT, totalIncludingTax float64

	occ.Items["other_total"].ExcludingTax = 0
	occ.Items["other_total"].VAT = 0
	occ.Items["other_total"].IncludingTax = 0

	for _, item := range occ.Items {
		// 跳过总计行
		if item == occ.Items["other_total"] {
			continue
		}

		// 跳过子项(子项已包含在父项中)
		if item.IsSubItem {
			item_up, ok := occ.Items[item.ParentID]
			if ok {
				item_up.ExcludingTax += item.ExcludingTax
			}
			item_up.CalculateTax(occ.VatRate)

			continue
		}

		// 安全生产费系数
		if item.SerialNumber == "9" {
			item.ExcludingTax = Cost * occ.SafeRate
		}

		if item.ExcludingTax == 0 {
			continue
		}

		// 确保税额计算正确
		item.CalculateTax(occ.VatRate)

		// 累加总计
		totalExcludingTax += item.ExcludingTax
		totalVAT += item.VAT
		totalIncludingTax += item.IncludingTax
	}

	occ.Items["other_total"].ExcludingTax = math.Round(totalExcludingTax*100) / 100
	occ.Items["other_total"].VAT = math.Round(totalVAT*100) / 100
	occ.Items["other_total"].IncludingTax = math.Round(totalIncludingTax*100) / 100

	occ.Totals = map[string]float64{
		"excluding_tax": math.Round(totalExcludingTax*100) / 100,
		"vat":           math.Round(totalVAT*100) / 100,
		"including_tax": math.Round(totalIncludingTax*100) / 100,
	}
}

// func NewOtherConstructionCostSheet() *OtherConstructionCost {
func (s *designServiceImpl) NewTab5(dcode string, atype int) *OtherConstructionCost {

	vatRate := config.Get().DesignConfig.VatRate
	safeRate := config.Get().DesignConfig.SafeRate

	sheet := &OtherConstructionCost{
		DesignCode: dcode,
		DesignType: atype,
		VatRate:    vatRate,
		SafeRate:   safeRate,

		Items:  make(map[string]*OtherCostItem),
		Totals: make(map[string]float64),
	}

	// 添加费用项
	sheet.Items["land_compensation"] = &OtherCostItem{
		// ID:           "land_compensation",
		LineNumber:   1,
		Name:         "建设用地及综合赔补费",
		SerialNumber: "1",
	}

	sheet.Items["construction_management"] = &OtherCostItem{
		// ID:           "construction_management",
		LineNumber:   2,
		Name:         "建设单位管理费",
		SerialNumber: "2",
	}

	sheet.Items["feasibility_study"] = &OtherCostItem{
		// ID:           "feasibility_study",
		LineNumber:   3,
		Name:         "可行性研究费",
		SerialNumber: "3",
	}

	//Research experiment
	sheet.Items["research_experiment"] = &OtherCostItem{
		// ID:           "research_experiment",
		LineNumber:   4,
		Name:         "研究实验费",
		SerialNumber: "4",
	}

	// 勘察设计费及其子项( 勘察设计费=勘察费+设计费)
	sheet.Items["design_survey"] = &OtherCostItem{
		// ID:           "design_survey",
		LineNumber:   5,
		Name:         "勘察设计费",
		SerialNumber: "5",
	}

	sheet.Items["survey_cost"] = &OtherCostItem{
		// ID:           "survey_cost",
		LineNumber:   6,
		Name:         "其中：勘察费",
		SerialNumber: "",
		IsSubItem:    true,
		ParentID:     "design_survey",
		VAT:          0,
	}

	sheet.Items["design_cost"] = &OtherCostItem{
		// ID:           "design_cost",
		LineNumber:   7,
		Name:         "其中：设计费",
		SerialNumber: "",
		IsSubItem:    true,
		ParentID:     "design_survey",
		VAT:          0,
	}

	sheet.Items["environmental_assessment"] = &OtherCostItem{
		// ID:           "environmental_assessment",
		LineNumber:   8,
		Name:         "环境影响评价费",
		SerialNumber: "6",
	}

	sheet.Items["safety_health"] = &OtherCostItem{
		// ID:           "safety_health",
		LineNumber:   9,
		Name:         "劳动安全卫生评价费",
		SerialNumber: "7",
	}

	sheet.Items["supervision"] = &OtherCostItem{
		// ID:           "supervision",
		LineNumber:   10,
		Name:         "建设工程监理费",
		SerialNumber: "8",
	}

	// 安全生产费(有特殊计算规则)
	sheet.Items["safety_production"] = &OtherCostItem{
		// ID:           "safety_production",
		LineNumber:   11,
		Name:         "安全生产费",
		SerialNumber: "9",
		// ExcludingTax: LaborCost * 0.015,
		// VAT:          LaborCost * 0.015 * 0.09,
		// IncludingTax: LaborCost * 0.015 * 1.09,

	}

	sheet.Items["quality_supervision"] = &OtherCostItem{
		// ID:           "quality_supervision",
		LineNumber:   12,
		Name:         "工程质量监督费",
		SerialNumber: "10",
	}

	// sheet.Items["norm_determination"] = &OtherCostItem{
	// 	// ID:           "norm_determination",
	// 	LineNumber:   13,
	// 	Name:         "工程定额测定费",
	// 	SerialNumber: "11",
	// }

	sheet.Items["introduction"] = &OtherCostItem{
		// ID:           "introduction",
		LineNumber:   13,
		Name:         "引进技术及引进设备其它费",
		SerialNumber: "11",
	}

	sheet.Items["insurance"] = &OtherCostItem{
		// ID:           "insurance",
		LineNumber:   14,
		Name:         "工程保险费",
		SerialNumber: "12",
	}

	sheet.Items["bidding_agency"] = &OtherCostItem{
		// ID:           "bidding_agency",
		LineNumber:   15,
		Name:         "招标代理费",
		SerialNumber: "13",
	}

	sheet.Items["patent_royalty"] = &OtherCostItem{
		// ID:           "patent_royalty",
		LineNumber:   16,
		Name:         "专利及专利技术使用费",
		SerialNumber: "14",
	}

	sheet.Items["other_total"] = &OtherCostItem{
		// ID:           "other_cost",
		LineNumber:   17,
		Name:         "总计",
		SerialNumber: "",
	}

	sheet.Items["operating_expenses"] = &OtherCostItem{
		// ID:           "operating_expenses",
		LineNumber:   18,
		Name:         "生产准备及开办费（运营费）",
		SerialNumber: "16",
	}

	// 其它附加费用
	otherFees, err := s.designDao.GetOtherFee(sheet.DesignCode, sheet.DesignType)
	if err != nil {
		logger.WithFields(map[string]interface{}{
			"layer":     "services",
			"operation": "GetOtherFee",
			"pcode":     sheet.DesignCode,
			"dtype":     sheet.DesignType,
		}).Errorf("GetOtherFee failed - error: %v", err)
	}

	for i := 0; i < len(otherFees); i++ {
		item := otherFees[i]
		iname := "AdditionalCost_" + strconv.Itoa(i+1)
		ex_tax := item.TaxIncluded / (1 + sheet.VatRate)
		tax := item.TaxIncluded - ex_tax
		sheet.Items[iname] = &OtherCostItem{
			Name:         item.Name,
			ExcludingTax: ex_tax,
			VAT:          tax,
			IncludingTax: item.TaxIncluded,
		}
	}

	return sheet
}

func (occ *OtherConstructionCost) PrintOtherConstructionCostSheet() {
	fmt.Println("其他建设成本表")
	fmt.Println("-----------------")
	for _, item := range occ.Items {
		fmt.Printf("%d. %s: %.2f\n", item.LineNumber, item.Name, item.ExcludingTax)
	}
	fmt.Println("-----------------")
	fmt.Printf("总计: %.2f\n", occ.Items["other_total"].IncludingTax)
	fmt.Println("-----------------")
	fmt.Printf("不含税总计: %.2f\n", occ.Items["other_total"].ExcludingTax)
	fmt.Println("-----------------")
}
